package com.shuda.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shuda.common.exception.BusinessException;
import com.shuda.common.utils.SecurityUtils;
import com.shuda.system.dto.RoleMenuDTO;
import com.shuda.system.entity.MenuEntity;
import com.shuda.system.entity.RoleEntity;
import com.shuda.system.entity.RoleMenuEntity;
import com.shuda.system.mapper.MenuMapper;
import com.shuda.system.mapper.RoleMapper;
import com.shuda.system.mapper.RoleMenuMapper;
import com.shuda.system.service.RoleMenuService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色菜单关联服务实现类
 */
@Service
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenuEntity> implements RoleMenuService {

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public List<RoleMenuDTO> getRoleMenus(Long roleId) {
        LambdaQueryWrapper<RoleMenuEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleMenuEntity::getRoleId, roleId)
                .eq(RoleMenuEntity::getDeleted, 0);

        List<RoleMenuEntity> entities = roleMenuMapper.selectList(wrapper);
        return entities.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void assignRoleMenus(Long roleId, List<Long> menuIds) {
        // 先删除现有菜单关联
        LambdaQueryWrapper<RoleMenuEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleMenuEntity::getRoleId, roleId);
        roleMenuMapper.delete(wrapper);

        // 添加新的菜单关联
        if (menuIds != null && !menuIds.isEmpty()) {
            for (Long menuId : menuIds) {
                // 验证菜单是否存在
                MenuEntity menu = menuMapper.selectById(menuId);
                if (menu == null || menu.getDeleted() == 1) {
                    throw new BusinessException("菜单不存在或已删除：" + menuId);
                }

                RoleMenuEntity roleMenuEntity = new RoleMenuEntity();
                roleMenuEntity.setRoleId(roleId);
                roleMenuEntity.setMenuId(menuId);
                roleMenuEntity.setCreateBy(SecurityUtils.getCurrentUsername());
                roleMenuEntity.setCreateTime(LocalDateTime.now());
                roleMenuEntity.setUpdateBy(SecurityUtils.getCurrentUsername());
                roleMenuEntity.setUpdateTime(LocalDateTime.now());
                roleMenuEntity.setDeleted(0);
                roleMenuMapper.insert(roleMenuEntity);
            }
        }
    }

    @Override
    @Transactional
    public void removeRoleMenu(Long roleId, Long menuId) {
        LambdaQueryWrapper<RoleMenuEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleMenuEntity::getRoleId, roleId)
                .eq(RoleMenuEntity::getMenuId, menuId);
        roleMenuMapper.delete(wrapper);
    }

    @Override
    public List<RoleMenuDTO> getMenuRoles(Long menuId) {
        LambdaQueryWrapper<RoleMenuEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleMenuEntity::getMenuId, menuId)
                .eq(RoleMenuEntity::getDeleted, 0);

        List<RoleMenuEntity> entities = roleMenuMapper.selectList(wrapper);
        return entities.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void batchAssignRoleMenus(List<Long> roleIds, Long menuId) {
        if (roleIds != null && !roleIds.isEmpty()) {
            // 验证菜单是否存在
            MenuEntity menu = menuMapper.selectById(menuId);
            if (menu == null || menu.getDeleted() == 1) {
                throw new BusinessException("菜单不存在或已删除：" + menuId);
            }

            for (Long roleId : roleIds) {
                // 检查是否已存在关联
                LambdaQueryWrapper<RoleMenuEntity> checkWrapper = new LambdaQueryWrapper<>();
                checkWrapper.eq(RoleMenuEntity::getRoleId, roleId)
                        .eq(RoleMenuEntity::getMenuId, menuId);
                
                if (roleMenuMapper.selectCount(checkWrapper) == 0) {
                    RoleMenuEntity roleMenuEntity = new RoleMenuEntity();
                    roleMenuEntity.setRoleId(roleId);
                    roleMenuEntity.setMenuId(menuId);
                    roleMenuEntity.setCreateBy(SecurityUtils.getCurrentUsername());
                    roleMenuEntity.setCreateTime(LocalDateTime.now());
                    roleMenuEntity.setUpdateBy(SecurityUtils.getCurrentUsername());
                    roleMenuEntity.setUpdateTime(LocalDateTime.now());
                    roleMenuEntity.setDeleted(0);
                    roleMenuMapper.insert(roleMenuEntity);
                }
            }
        }
    }

    @Override
    @Transactional
    public void batchRemoveRoleMenus(List<Long> roleIds, Long menuId) {
        if (roleIds != null && !roleIds.isEmpty()) {
            LambdaQueryWrapper<RoleMenuEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(RoleMenuEntity::getRoleId, roleIds)
                    .eq(RoleMenuEntity::getMenuId, menuId);
            roleMenuMapper.delete(wrapper);
        }
    }

    @Override
    public List<Long> getRoleMenuIds(Long roleId) {
        LambdaQueryWrapper<RoleMenuEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RoleMenuEntity::getRoleId, roleId)
                .eq(RoleMenuEntity::getDeleted, 0);

        List<RoleMenuEntity> entities = roleMenuMapper.selectList(wrapper);
        return entities.stream()
                .map(RoleMenuEntity::getMenuId)
                .collect(Collectors.toList());
    }

    private RoleMenuDTO convertToDTO(RoleMenuEntity entity) {
        RoleMenuDTO dto = new RoleMenuDTO();
        BeanUtils.copyProperties(entity, dto);

        // 查询角色信息
        RoleEntity role = roleMapper.selectById(entity.getRoleId());
        if (role != null) {
            dto.setRoleName(role.getRoleName());
            dto.setRoleCode(role.getRoleCode());
        }

        // 查询菜单信息
        MenuEntity menu = menuMapper.selectById(entity.getMenuId());
        if (menu != null) {
            dto.setMenuName(menu.getMenuName());
            dto.setMenuCode(menu.getMenuCode());
            dto.setMenuPath(menu.getPath());
        }

        return dto;
    }
}